package com.arraymasterx.controller;

import com.arraymasterx.algorithm.SortingAlgorithms;
import com.arraymasterx.exception.AlgorithmException;
import com.arraymasterx.model.SortRequest;
import com.arraymasterx.model.SortResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/sort")
@Tag(name = "Sorting Algorithms", description = "Operations related to sorting algorithms")
public class SortController {

    private final SortingAlgorithms sortingAlgorithms;

    @Autowired
    public SortController(SortingAlgorithms sortingAlgorithms) {
        this.sortingAlgorithms = sortingAlgorithms;
    }

    @PostMapping("/bubble")
    @Operation(summary = "Perform bubble sort on an array",
        responses = {
            @ApiResponse(responseCode = "200", description = "Successful operation",
                content = @Content(schema = @Schema(implementation = SortResponse.class))),
            @ApiResponse(responseCode = "400", description = "Invalid input")
        })
    public ResponseEntity<SortResponse> bubbleSort(@RequestBody SortRequest request) {
        try {
            int[] sortedArray = sortingAlgorithms.bubbleSort(request.getArray().clone());
            return ResponseEntity.ok(new SortResponse(sortedArray, "Bubble Sort"));
        } catch (IllegalArgumentException e) {
            throw new AlgorithmException(e.getMessage());
        }
    }

    @PostMapping("/quick")
    @Operation(summary = "Perform quick sort on an array",
        responses = {
            @ApiResponse(responseCode = "200", description = "Successful operation",
                content = @Content(schema = @Schema(implementation = SortResponse.class))),
            @ApiResponse(responseCode = "400", description = "Invalid input")
        })
    public ResponseEntity<SortResponse> quickSort(@RequestBody SortRequest request) {
        try {
            int[] sortedArray = sortingAlgorithms.quickSort(request.getArray().clone());
            return ResponseEntity.ok(new SortResponse(sortedArray, "Quick Sort"));
        } catch (IllegalArgumentException e) {
            throw new AlgorithmException(e.getMessage());
        }
    }

    @PostMapping("/merge")
    @Operation(summary = "Perform merge sort on an array",
        responses = {
            @ApiResponse(responseCode = "200", description = "Successful operation",
                content = @Content(schema = @Schema(implementation = SortResponse.class))),
            @ApiResponse(responseCode = "400", description = "Invalid input")
        })
    public ResponseEntity<SortResponse> mergeSort(@RequestBody SortRequest request) {
        try {
            int[] sortedArray = sortingAlgorithms.mergeSort(request.getArray().clone());
            return ResponseEntity.ok(new SortResponse(sortedArray, "Merge Sort"));
        } catch (IllegalArgumentException e) {
            throw new AlgorithmException(e.getMessage());
        }
    }

    @PostMapping("/heap")
    @Operation(summary = "Perform heap sort on an array",
        responses = {
            @ApiResponse(responseCode = "200", description = "Successful operation",
                content = @Content(schema = @Schema(implementation = SortResponse.class))),
            @ApiResponse(responseCode = "400", description = "Invalid input")
        })
    public ResponseEntity<SortResponse> heapSort(@RequestBody SortRequest request) {
        try {
            int[] sortedArray = sortingAlgorithms.heapSort(request.getArray().clone());
            return ResponseEntity.ok(new SortResponse(sortedArray, "Heap Sort"));
        } catch (IllegalArgumentException e) {
            throw new AlgorithmException(e.getMessage());
        }
    }
}